package com.df.gamesynctest.entity;

import com.df.gamesynctest.handler.MsgHandler;
import com.df.gamesynctest.msg.MsgWrapper;
import com.df.gamesynctest.msg.S2C_PlayerMove;
import com.df.gamesynctest.msg.S2C_SynAroundObjs;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;


@Slf4j
public class GameMap extends Thread{
    private  static GameMap gameMap = new GameMap();
    private GameMap() {
        init();
    }

    public  static GameMap getInstance() {
         return gameMap;
     }
    public int id = 1;//地图id
    public int width = 100;//地图宽
    public int height = 100;//地图高
    public int viewWidth = 20;//地图视野范围
    public int[][] map;//地图阻挡数据
    public List<Player> players = new ArrayList<>();//地图玩家数据
    public List<Monster> monsters = new ArrayList<>();//地图怪物数据
    long loopStartTime;//循环开始时间
    long loopEndTime;//循环开始时间
    double lastFrameTime;//当前帧开始时间距离上一帧开始时间的间隔，毫秒
    //TODO 地图触发器
    LinkedBlockingQueue<MsgWrapper> msgQue = new LinkedBlockingQueue<>();

    public void init(){
         //TODO 创建怪物
        Random random = new Random();
        for (int i = 0; i < 0; i++) {
            Monster monster = new Monster();
            monster.id = i;
            monster.map = this;
            int[] array = random.ints(2, 0, 20).toArray();
            monster.pos = new Vector2(array[0],array[1]);
            System.out.println("怪物初始位置："+monster.pos);
            monster.moveTarget = monster.pos.lone();
            monster.script = new GameMapMonsterScript(monster);


            monsters.add(monster);
        }
     }

     //找到寻找点周围九宫格内的玩家
     public List<Player> findAroundPlayer(Vector2 origin){
         Vector2 orgin9 = cal9pos(origin);
         List<Player> findPlayers = new ArrayList<>();
         for (Player player : players) {
             Vector2 player9 = cal9pos(player.pos);
             if(Math.abs(orgin9.x-player9.x)<=1 && Math.abs(orgin9.y-player9.y)<=1){
                 findPlayers.add(player);
             }
         }
         return findPlayers;
     }
    public List<Monster> findAroundMonster(Vector2 origin){
//        System.out.println("玩家的坐标："+origin);
        Vector2 origin9 = cal9pos(origin);
        List<Monster> findMonsters = new ArrayList<>();
        for (Monster monster : monsters) {
//            System.out.println("monster的坐标："+monster.pos);
            Vector2 monster9 = cal9pos(monster.pos);
            if(Math.abs(origin9.x-monster9.x)<=1 && Math.abs(origin9.y-monster9.y)<=1){
                findMonsters.add(monster);
            }
        }
        return findMonsters;
    }


    public void receiveMapMsg(MsgWrapper msgWrapper){
        if(msgWrapper==null){
            return;
        }
        msgQue.offer(msgWrapper);
    }


    @Override
    public void run() {
        if(loopStartTime== 0){
            loopStartTime = System.currentTimeMillis();
        }
        while (true){
            long now =  System.currentTimeMillis();
            lastFrameTime = (now - loopStartTime)/1000.0d;
            loopStartTime = now;
            update();

            long endTime = System.currentTimeMillis();
            long frameExcuteTime = endTime - loopStartTime;
            if(frameExcuteTime < 100){
                try {
                    Thread.sleep(100-frameExcuteTime);
                }catch (InterruptedException e){
                    System.out.println("地图线程被打断");
                }
            }
        }
    }

    private void update() {
        //处理队列的消息
        while (msgQue.size() > 0){
            MsgWrapper poll = msgQue.poll();
            //处理消息
            MsgHandler.getInstance().handleMsg(poll);
        }
        //处理移动
        playerMove();
        //怪物脚本执行
        for (Monster monster : monsters) {
            if(monster.script!=null){
                try {
                    monster.script.update(lastFrameTime);
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        }
    }

    private void playerMove() {
        //角色移动
        for (Player player : players) {
            //移动和AOI
            if(player.moveDir.x==0 && player.moveDir.y==0){
                continue;
            }
            Vector2 distance = player.moveDir.normalize().multiply(player.speed * lastFrameTime);
            player.pos = player.pos.plus(distance);
            //TODO 移动后AOI
        }
        //NPC移动
    }
    public Vector2 cal9pos(Vector2 pos){
        Vector2 r = new Vector2();
        r.x =  pos.x/viewWidth + pos.x%viewWidth>0?1:0;;
        r.y =  pos.y/viewWidth +pos.y%viewWidth>0?1:0;
        return r;
    }
    public void playerEnterMap(Player player) {
        //TODO 进入的生命周期 进入前(退出之前地图，清理之前地图的相关数据,比如buff等等)
        if(players.contains(player)){
            return;
        }
        players.add(player);
        player.map = this;
        //同步周围玩家，根据地图视野找九宫格内的玩家，怪物，npc等
        //TODO 同步周围怪物
        //同步给周围的玩家，九宫格算法
        List<Monster> aroundMonster =findAroundMonster(player.pos);
        List<MonsterData> sendMonsterData = new ArrayList<>();
        for (Monster monster : aroundMonster) {
            MonsterData d = new MonsterData();
            d.id = monster.id;
            d.posX = (float) monster.pos.x;
            d.posY = (float) monster.pos.y;
            d.moveTargetX = (float) monster.moveTarget.x;
            d.moveTargetY = (float) monster.moveTarget.y;
            d.speed = monster.speed;
            sendMonsterData.add(d);
        }
        System.out.println("玩家进入地图，周围的怪物数量："+aroundMonster.size());

        List<Player> aroundPlayers =findAroundPlayer(player.pos);
        aroundPlayers.remove(player);
        List<PlayerData> sendPlayerData = new ArrayList<>();
        for (Player aroundPlayer : aroundPlayers) {
            PlayerData playerData = new PlayerData();
            playerData.id = aroundPlayer.id;
            playerData.posX = (float) aroundPlayer.pos.x;
            playerData.posY = (float) aroundPlayer.pos.y;
            playerData.moveDirX  = (float) aroundPlayer.moveDir.x;
            playerData.moveDirY  = (float) aroundPlayer.moveDir.y;
            playerData.speed = aroundPlayer.speed;
            sendPlayerData.add(playerData);
        }

        S2C_SynAroundObjs msg = new S2C_SynAroundObjs();
        msg.monsterList.addAll(sendMonsterData);
        msg.playerList.addAll(sendPlayerData);
        UserManager.getInstance().sendMsg(player,msg);

        if(aroundPlayers.size()>0){
            S2C_SynAroundObjs own2other = new S2C_SynAroundObjs();
            PlayerData playerData = new PlayerData();
            playerData.id = player.id;
            playerData.posX = (float) player.pos.x;
            playerData.posY = (float) player.pos.y;
            playerData.moveDirX  = (float) player.moveDir.x;
            playerData.moveDirY  = (float) player.moveDir.y;
            playerData.speed = player.speed;
            own2other.playerList.add(playerData);
            //将自己同步给别人
            UserManager.getInstance().broadCastMsg(aroundPlayers,own2other);
        }

        //TODO 进入后(进入后地图，创建新的地图数据，比如buff等等)
    }
}
